package cn.nexttec.noteplayer.common

import android.app.Activity
import android.content.Context
import android.util.Log
import android.view.View
import net.sourceforge.pinyin4j.PinyinHelper
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.security.MessageDigest
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Date
import java.util.regex.Pattern

infix fun String.debug(message: Any) {
    if (isPrimitiveType(message)) {
        Log.i(this, message.toString())
    } else {
        Log.i(this, message.gson())
    }
}

infix fun String.ld(message: Any) {
    if (isPrimitiveType(message)) {
        Log.d(this, message.toString())
    } else {
        Log.d(this, message.gson())
    }
}




fun String.md5(): String {
    val bytes = MessageDigest.getInstance("MD5").digest(toByteArray())
    return bytes.joinToString("") { "%02x".format(it) }
}

fun Long.formatMillsecond(): String {
    val totalSeconds = this / 1000
    val seconds = (totalSeconds % 60).toInt()
    val minutes = ((totalSeconds / 60) % 60).toInt()
    val hours = (totalSeconds / 3600).toInt()

    return if (hours > 0) {
        String.format("%d:%02d:%02d", hours, minutes, seconds)
    } else {
        String.format("%02d:%02d", minutes, seconds)
    }
}

fun formatSpeed(speed: Float): String {
    return if (speed == 1f || speed == 2f) {
        String.format("%.1fx", speed)
    } else {
        String.format("%.2fx", speed)
    }
}

@Throws(BadHanyuPinyinOutputFormatCombination::class)
fun String.getPinyin(): String {
    val format = HanyuPinyinOutputFormat()
    format.caseType = HanyuPinyinCaseType.LOWERCASE
    format.toneType = HanyuPinyinToneType.WITHOUT_TONE
    format.vCharType = HanyuPinyinVCharType.WITH_V
    val output = StringBuilder()
    val input = this.toCharArray()
    for (c in input) {
        val pattern = Pattern.compile("[\\u4E00-\\u9FA5]")
        val matcher = pattern.matcher(c.toString())
        if (matcher.matches()) {
            val ret = PinyinHelper.toHanyuPinyinStringArray(c, format)
            output.append(ret[0])
        } else {
            output.append(c.toString())
        }
    }
    return output.toString()
}

fun String.padArabicNumbersToLength(length: Int = 9): String {
    val regex = Regex("""\d+""")
    return regex.replace(this) {
        it.value.padStart(length, '0')
    }
}

fun String.chineseNumberToArabic(): Int {
    val digitMap = mapOf(
        '零' to 0, '一' to 1, '二' to 2, '两' to 2, '三' to 3, '四' to 4, '五' to 5,
        '六' to 6, '七' to 7, '八' to 8, '九' to 9
    )

    var result = 0
    var temp = 0
    var lastUnit = 1
    val chars = this.toCharArray()

    for (i in chars.indices) {
        val c = chars[i]
        when (c) {
            '十' -> {
                temp = if (i == 0) 1 else temp
                result += temp * 10
                temp = 0
                lastUnit = 10
            }
            else -> {
                val digit = digitMap[c] ?: return 0
                temp = digit
                lastUnit = 1
                if (i == chars.lastIndex) result += temp
                else if (chars[i + 1] != '十') result += temp
            }
        }
    }

    return result
}


fun String.convertChineseNumbersInText(): String {
    val chineseNumRegex = Regex("[零一二两三四五六七八九十]+")
    return replace(chineseNumRegex) {
        val chinese = it.value
        val arabic = chinese.chineseNumberToArabic()
        arabic.toString()
    }
}

fun File.formatName():String{
    return nameWithoutExtension.convertChineseNumbersInText().padArabicNumbersToLength().getPinyin()
}

fun formatName(name:String):String{
    return name.convertChineseNumbersInText().padArabicNumbersToLength().getPinyin()
}

fun setImmersiveMode(activity: Activity) {
    activity.window.decorView.systemUiVisibility = (
            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            )
}

fun Context.isTablet(): Boolean {
    val metrics = resources.displayMetrics
    val widthDp = metrics.widthPixels / metrics.density
    val heightDp = metrics.heightPixels / metrics.density
    val smallestWidthDp = minOf(widthDp, heightDp)
    return smallestWidthDp >= 600
}

//将从 ExoPlayer 获取的 position: Long（以毫秒为单位）格式化为 hh:mm:ss 格式（如果小时为 0，则返回 mm:ss）：
fun Long.formatPosition(): String {
    val totalSeconds = this / 1000
    val hours = totalSeconds / 3600
    val minutes = (totalSeconds % 3600) / 60
    val seconds = totalSeconds % 60

    return if (hours > 0) {
        String.format("%02d:%02d:%02d", hours, minutes, seconds)
    } else {
        String.format("%02d:%02d", minutes, seconds)
    }
}

fun formatDate(date: Date, pattern: String = "yyyy-MM-dd HH:mm:ss"): String {
    val formatter = DateTimeFormatter.ofPattern(pattern)
    val instant = date.toInstant()
    val zonedDateTime = instant.atZone(ZoneId.systemDefault())
    return formatter.format(zonedDateTime)
}


fun copyFile(srcFile: File, destFile: File, deleteSource: Boolean = true): Boolean {
    if (!srcFile.exists()) return false

    try {
        // 创建目标文件夹（如果不存在）
        destFile.parentFile?.let {
            if (!it.exists()) it.mkdirs()
        }

        FileInputStream(srcFile).use { input ->
            FileOutputStream(destFile).use { output ->
                val buffer = ByteArray(4096)
                var bytesRead: Int
                while (input.read(buffer).also { bytesRead = it } != -1) {
                    output.write(buffer, 0, bytesRead)
                }
            }
        }

        // 根据参数决定是否删除源文件
        if (deleteSource) {
            if (!srcFile.delete()) {
                println("Warning: 源文件删除失败：${srcFile.absolutePath}")
            }
        }

        return true
    } catch (e: IOException) {
        e.printStackTrace()
    }
    return false
}
